package org.example.quartz.task;

import cn.hutool.db.Entity;
import cn.hutool.db.Session;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.example.quartz.service.LogService;
import org.example.quartz.service.OrgService;
import org.example.quartz.service.UtilService;
import org.example.quartz.util.DataSourceUtil;
import org.quartz.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
// 再Job被执行结束后，将会更新JobDataMap，这样下次Job执行后悔使用新的值而不是初始值
@PersistJobDataAfterExecution
// 同一时间将只有一个Job实例被执行，为了避免并发问题导致数据紊乱，建议这两个注解一起使用
@DisallowConcurrentExecution
public class ItemQuartz implements QuartzTaskJob {


    Map<String, Object> gsMap = DataSourceUtil.getGS();
    //全局接口配置
    String IP = (String) gsMap.get("IP");
    String PORT = (String) gsMap.get("PORT");
    String ECC = (String) gsMap.get("ECC");
    String Bearer = (String) gsMap.get("Bearer");

    //日志
    LogService loginfo = SpringUtil.getBean(LogService.class);
    //orgService
    OrgService orgService = SpringUtil.getBean(OrgService.class);
    //orgService
    UtilService utilService = SpringUtil.getBean(UtilService.class);
    /**
     * 项目接口
     * 接口地址：GSCloud文档3.7
     * http://ip:port/api/jg/syncbddata/v1.0/bdsyncinterface/syncHsxm
     **/
    @SneakyThrows
    @Override
    public void execute(JobExecutionContext context) {
        //传入变量 lastTime 最后抓取时间
        //链接BIP数据库，查询出需要同步的数据，根据TS时间进行判断。
        //TS从中间库表获取到最后一次更新时间，根据此时间进行增量查询推送；
        //中间库日志表记录推送日志，成功、失败、返回信息等（备查）
        //中间库记录最后推送数据的时间，根据时间进行下次查询的条件；
        String methodName = "ItemQuartz";
        JdbcTemplate jdbcTemplate = SpringUtil.getBean(JdbcTemplate.class);
        //查询核算项目-中间配置表，看有多少需要同步的核算项目，让后做循环处理
        String itemClassSQL = "SELECT\n" +
                "\tid,\n" +
                "\tnum,\n" +
                "\tdoccode,\n" +
                "\tdocname,\n" +
                "\tgscode,\n" +
                "\ttablename,\n" +
                "\ttablekey,\n" +
                "\tcodekey,\n" +
                "\tnamekey,\n" +
                "\tfzpk,\n" +
                "\tfreekey,\n" +
                "\tistrue,\n" +
                "\tts \n" +
                "FROM\n" +
                "\tfreemap f \n" +
                "WHERE\n" +
                "\tf.istrue = 'NO'";
        List<Map<String, Object>> itemClassMaps = jdbcTemplate.queryForList(itemClassSQL);
        for(Map<String, Object> itemClassObj:itemClassMaps){
            String itemClass = methodName+"-"+itemClassObj.get("docname");
            String docCode = (String) itemClassObj.get("gscode");
            //1、查询时间
            String ts = utilService.getTs(itemClass, jdbcTemplate);
            //2、根据时间查询数据集 (停用和删除的过滤掉，暂不考虑，线下处理)
            String selectSQL = "SELECT" +
                    " TO_CHAR(SYSDATE,'YYYY') AS YEAR, " +
                    " "+itemClassObj.get("codekey")+" AS CODE,"+
                    " "+itemClassObj.get("namekey")+" AS NAME,"+
                    " "+itemClassObj.get("tablekey")+" AS ID," +
                    " TS AS TS" +
                    " FROM" +
                    " "+itemClassObj.get("tablename")+""+
                    " WHERE" +
                    " DR = 0" +
//                    " AND " +
//                    " ENABLESTATE = 2" +
                    " AND " +
                    " TS >'"+ts+"'" +
                    " ORDER BY TS ASC";
            //查询数据，根据数据结果推送给GS浪潮
            Session oracleSession = DataSourceUtil.getOracleSession();
            List<Entity> query = oracleSession.query(selectSQL);
            //拼装数据，推送给浪潮
            if(query.size()>0){
                for (Map<String, Object> gSmap : query) {
                    //根据组织编码，查询出账套信息，如果有多个账套，轮询进行处理
                    List<Map<String, Object>> yyztCodeMap = orgService.selectAllZtCode(jdbcTemplate);
                    //账簿轮询
                    for (int x = 0; x < yyztCodeMap.size(); x++) {
                        String yyztCode = (String) yyztCodeMap.get(x).get("yyztCode");
                        String orgCode = (String) yyztCodeMap.get(x).get("gsCode");
                        String CATEGORY = docCode;
                        String GsJson =
                                "{\n" +
                                        "    \"YEAR\":\"" + gSmap.get("YEAR") + "\",\n" +
                                        "    \"CODE\":\""+yyztCode + gSmap.get("CODE") + "\",\n" +
                                        "    \"NAME\":\"" + gSmap.get("CODE") + gSmap.get("NAME") + yyztCode + "\",\n" +
                                        "    \"ORGCODE\":\"" + orgCode + "\",\n" +
                                        "    \"CATEGORY\":\"" + CATEGORY+"\",\n" +
                                        "    \"PARENTCODE\":\"\",\n" +
                                        "    \"FULLNAME\":\"\",\n" +
                                        "    \"SECRETLEVEL\":\"\"\n" +
                                        "}";
                        //调用GS接口，推送给GS浪潮，获取返回值;
                        //1、推送用户档案
                        String gsUrl = "https://" + IP + ":" + PORT + "/api/jg/syncbddata/v1.0/bdsyncinterface/syncHsxm";
                        String returnMSG = HttpRequest.post(gsUrl)
                                .header("Content-Type", "application/json")
                                .header("Accept-Language", "zh-CHS")
                                .header("X-ECC-Current-Tenant", ECC)
                                .header("Authorization", Bearer).timeout(200000)
                                .body(GsJson).execute().body();
                        if (!returnMSG.isEmpty()) {
                            String logInsert = "";
                            JSONObject returnObj = JSONObject.parseObject(returnMSG);
                            //成功
                            if (returnObj.get("code").equals("0") ) {
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, itemClass, LocalDateTime.now().toString(), "成功", GsJson, returnMSG, "", "", gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                  //  System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                                //失败
                            } else if (returnObj.get("code").equals("1")) {
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, itemClass, LocalDateTime.now().toString(), "失败", GsJson, returnMSG, "", "", gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                  //  System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                            }else if(returnObj.get("code")==null && ("").equals(returnObj.get("code"))){
                                //写入日志表
                                int loginsert = loginfo.loginfo(jdbcTemplate, methodName, LocalDateTime.now().toString(), "数据返回异常", GsJson, returnMSG, "",  (String) gSmap.get("ID"), gsUrl, (String) gSmap.get("TS"));
                                if (loginsert > 0) {
                                    System.out.println("日志写入成功！！");
                                } else {
                                    System.out.println("日志写入失败！！");
                                }
                            }
                        }
                    }
                }
            }else{
                System.out.println("暂无新数据推送");
            }
        }
    }
}
